﻿using System;
using System.IO;

namespace DirectoryCleaner
{
    /// <summary>
    /// Cleaner encapsulates the operations that clean directories of a given file type.
    /// </summary>
    public sealed class Cleaner
    {
        private readonly string rootDirectory;
        private readonly string[] fileExtensions;

        /// <summary>
        /// Creates and initializes a new <see cref="Cleaner"/> instance.
        /// </summary>
        /// <param name="rootDirectory">Root directory of directories to clean.</param>
        /// <param name="fileExtensions">File extensions of files to remove.</param>
        /// <exception cref="ArgumentNullException">
        /// <para>
        /// <strong>rootDirectory</strong> is <strong>null</strong>;
        /// </para>
        /// <para>
        /// or
        /// </para>
        /// <para>
        /// <strong>fileExtensions</strong> is <strong>null</strong>.
        /// </para>
        /// </exception>
        public Cleaner(string rootDirectory, string[] fileExtensions)
        {
            // verify preconditions
            if (rootDirectory == null)
            {
                throw new ArgumentNullException("rootDirectory");
            }
            else if (fileExtensions == null)
            {
                throw new ArgumentNullException("fileExtensions");
            }

            this.rootDirectory = rootDirectory;
            this.fileExtensions = fileExtensions;
        }

        /// <summary>
        /// Invokes the cleaning of the directory specified.
        /// </summary>
        /// <exception cref="ArgumentException">Directory specified does not exist.</exception>
        public void Clean()
        {
            if (!Directory.Exists(rootDirectory))
            {
                throw new ArgumentException(string.Format("Directory: {0} does not exist.", rootDirectory));
            }

            CleanDirs(rootDirectory, fileExtensions);
        }

        /// <summary>
        /// Looks at each file in each directory to check whether or not it should be deleted.
        /// </summary>
        /// <param name="rootDirectory">Root directory of directories to clean.</param>
        /// <param name="fileExtensions">File extensions of files to remove.</param>
        private void CleanDirs(string rootDirectory, string[] fileExtensions)
        {
            // check for files within rootDirectory for a file with an extension listed in fileExtensions to delete
            foreach (string file in Directory.GetFiles(rootDirectory))
            {
                bool match = false;
                foreach (string ext in fileExtensions)
                {
                    if (ext == Path.GetExtension(file))
                    {
                        match = true; // we want to preserve this file
                        break;
                    }
                }

                if (!match)
                {
                    // we don't want to preserve this file
                    File.Delete(file);
                }
            }

            // check all subdirectories of rootDirectory for files with the specified extensions to delete
            foreach (string dir in Directory.GetDirectories(rootDirectory))
            {
                CleanDirs(dir, fileExtensions);
            }
        }
    }
}
